import os
import soundfile as sf
import traceback

os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'
try:
    import torch
    import torch_npu

    if torch.npu.is_available() :
        device = "npu:0"
    elif torch.cuda.is_available() :
        device = "cuda"
    else:
        device = 'cpu'
    device = 'npu' if torch.npu.is_available() else 'cpu'
except Exception as e :
    traceback.print_exc()
    device = 'cpu'

from others.neuttsAirMain.neuttsair.neutts import NeuTTSAir
from utils.loggingConfig import get_logger


root_path = os.path.abspath(__file__)
for i in range(2):
    root_path = os.path.dirname(root_path)

samplesPath = os.path.join(root_path , 'others/neuttsAirMain/samples')
outputsDir = os.path.join(root_path , 'outputs/')

logger = get_logger('')

logger.info(f"########## device {device}")

# class neuttsAirModel():
#     """ neuttsAir 模型 """
#     _instance = None
#
#     def __init__(self ):
#         """
#         @param backbone_device:
#         @param codec_device:
#         """
#         NEUTTSAIR_BACKBONE = os.getenv('NEUTTSAIR_BACKBONE' , 'neuphonic/neutts-air-q4-gguf')
#         NEUTTSAIR_CODEC = os.getenv('NEUTTSAIR_CODEC', 'neuphonic/neucodec')
#         if self._instance is not None:
#             return self._instance
#         else:
#             self._instance = NeuTTSAir(backbone_repo=NEUTTSAIR_BACKBONE, backbone_device=device,
#                             codec_repo=NEUTTSAIR_CODEC, codec_device=device)
#             print("######## self._instance " , type(self._instance ))
#             return self._instance


class neuttsAirModel():
    """ neuttsAir 模型 """
    _instance = None
    _initialized = False

    def __new__(cls):
        """
        单例模式：确保只创建一个实例
        """
        if cls._instance is None:
            cls._instance = super(neuttsAirModel, cls).__new__(cls)
        return cls._instance

    def __init__(self):
        """
        @param backbone_device:
        @param codec_device:
        """
        # 避免重复初始化
        if neuttsAirModel._initialized:
            return

        NEUTTSAIR_BACKBONE = os.getenv('NEUTTSAIR_BACKBONE', 'neuphonic/neutts-air-q4-gguf')
        NEUTTSAIR_CODEC = os.getenv('NEUTTSAIR_CODEC', 'neuphonic/neucodec')
        self._instance = NeuTTSAir(backbone_repo=NEUTTSAIR_BACKBONE, backbone_device=device,
                                   codec_repo=NEUTTSAIR_CODEC, codec_device=device)
        print("######## self._instance ", type(self._instance))
        neuttsAirModel._initialized = True


async def neuttsAirService(req_id : str, input_text:str , ref_type:str):
    '''
    音频服务
    @param req_id：请求id
    @param input_text：输入文本转音频
    @param ref_type：参看发音类型
    @return 如果生成音频文件，返回这个文件的地址
    '''
    logger.info(f'req_id:{req_id} input_text:{input_text} ref_type:{ref_type}')
    try:
        tts = neuttsAirModel()._instance
        print("####################### tts" , tts)
        if ref_type == 'jo':
            ref_text = os.path.join(samplesPath , "jo.txt")
            ref_audio_path = os.path.join(samplesPath , "jo.wav")
        else:
            ref_text = os.path.join(samplesPath, "dave.txt")
            ref_audio_path = os.path.join(samplesPath, "dave.wav")

        ref_text = open(ref_text, "r").read().strip()
        ref_codes = tts.encode_reference(ref_audio_path)

        wav = tts.infer(input_text, ref_codes, ref_text)
        outpath = os.path.join(outputsDir , f'{req_id}-test.wav')
        sf.write(outpath, wav, 24000)
        return outpath
    except Exception as e:
        msg = traceback.format_exc()
        logger.error(f'req_id:{req_id}  [error_msg]:{msg}')
    # finally:
    #     try:
    #         if tts:
    #             if tts.backbone:
    #                 tts.backbone.close()
    #     except Exception as e:
    #         traceback.print_exc()
    #         msg = traceback.format_exc()
    #         logger.error(f'req_id:{req_id} [error_msg]:{msg}')
    return
